# -*- coding: utf-8 -*-
"""
Module Description: 基础orm类库
Date: 2016/11/9
Author:Bai Jin Ping

参考：
连接池：http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#pool
自动重连：http://docs.peewee-orm.com/en/latest/peewee/database.html?#automatic-reconnect
"""
import copy
import peewee
from playhouse.pool import PooledMySQLDatabase
from playhouse.shortcuts import RetryOperationalError

from common.service_config import config, DalMode


class AutoReconnectMySQLPoolDatabase(RetryOperationalError, PooledMySQLDatabase):
    """
    若MySQL因为连接的空闲时间超过wait_timeout而主动关闭连接，则自动重连
    """
    def initialize_connection(self, conn):
        """
        连接创建成功后的一些设置
        :param conn: pymysql.connections.Connection object
        :return:
        """
        # 可以设置连接会话的一些属性
        pass


def get_peewee_database():
    # 创建数据库连接池对象
    _db_cfg = copy.deepcopy(config['dbconf']['character'])
    database = AutoReconnectMySQLPoolDatabase(_db_cfg['db'],
                                              host=_db_cfg['host'],
                                              user=_db_cfg['user'],
                                              passwd=_db_cfg['passwd'],
                                              port=_db_cfg['port'],
                                              charset=_db_cfg['charset'],
                                              max_connections=50)
    return database


def get_profile_database():
    # 创建数据库连接池对象
    _db_cfg = copy.deepcopy(config['dbconf']['profile'])
    database = AutoReconnectMySQLPoolDatabase(_db_cfg['db'],
                                              host=_db_cfg['host'],
                                              user=_db_cfg['user'],
                                              passwd=_db_cfg['passwd'],
                                              port=_db_cfg['port'],
                                              charset=_db_cfg['charset'],
                                              max_connections=50)
    return database


# 使用数据库代理
_db_pool = peewee.Proxy()
_db_profile_pool = peewee.Proxy()


def get_database_pool():
    """
    获得peewee数据库连接池对象
    :return:
    """
    return _db_pool


def close_database_pool():
    """
    关闭peewee数据库连接池
    :return:
    """
    if _db_pool:
        _db_pool.close_all()


def get_profile_pool():
    """
    获得peewee profile数据库连接池对象
    :return:
    """
    return _db_profile_pool


def close_profile_pool():
    """
    显式关闭peewee profile数据库连接池
    :return:
    """
    if _db_profile_pool:
        _db_profile_pool.manual_close()


class BaseCharacterModel(peewee.Model):
    """
    角色数据模型基类
    """
    class Meta:
        database = _db_pool

        # 生成的表名等于模型类名
        db_table_func = lambda mdl: mdl.__name__

        # 仅保存修改的字段到数据库
        only_save_dirty = True


class BaseProfileModel(BaseCharacterModel):

    class Meta:
        database = _db_profile_pool

        # 生成的表名等于模型类名
        db_table_func = lambda mdl: mdl.__name__

        # 仅保存修改的字段到数据库
        only_save_dirty = True


class TranslatedField(peewee.CharField):
    db_field = 'string'
